﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Data;
using Jb.Common.Extensions;
using Jb.Domain;
using Jb.Web.ViewModels;
using Jb.Web.Utility;
using AutoMapper;
using Jb.Web.ViewModels.UtilityModels;
using Jb.Common.Xml;

namespace Jb.Web.Areas.Admin.Controllers
{
    [Authorize(Roles = "Admin")]
    public class CategoryController : BaseController
    {
		private JbEntities _Context = new JbEntities();
        
		#region Constructors
		public CategoryController()
		{
		}

		public CategoryController(UserViewModel currentUser)
			: base(currentUser)
        {
        }
		#endregion Constructors

		#region Action Methods

        /// <summary>
        /// Default action for this Controller. Shows the list of categories
        /// </summary>
        /// <returns></returns>
        public ActionResult Index()
        {
            return View("List", BuildCategoryListConfig());
        }

        /// <summary>
        /// Shows the list of categories
        /// </summary>
        /// <returns></returns>
		public ActionResult List()
        {
            return View(BuildCategoryListConfig());
        }

        /// <summary>
        /// Gets a Category from Database to edit
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ActionResult Edit(int id = 0, String IsSaved = null)
        {
            Category entity = id == 0 ? new Category() : _Context.Categories.FirstOrDefault(P => P.ID == id);
            CategoryViewModel viewModel = Mapper.Map<Category, CategoryViewModel>(entity);
            if (String.Compare(IsSaved, "true", true) == 0)
                ViewData[AppConstants.ViewDataKeys.SAVED] = true;            
            return View(viewModel);
        }

        /// <summary>
        /// Saves Category Information into the Database
        /// </summary>
        /// <param name="viewModel"></param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult Edit(CategoryViewModel viewModel)
        {
            if (!ModelState.IsValid)
                return View(viewModel);

            #region ZGL Validation

            ///Check for Invalid Property Definition XML 
            if (!viewModel.PropertyDefinition.IsEmpty())
            {
                try
                {
                    //var childs = ApplicationCache.Categories.FirstOrDefault(P => P.ParentID == viewModel.ID);
                    //var parentCategory = ApplicationCache.Categories.FirstOrDefault(P => P.ID == viewModel.ParentID.GetValueOrDefault());
                    //if (childs != null || viewModel.ParentID.GetValueOrDefault() == 0 || (parentCategory != null && parentCategory.ParentCategory == null))
                    //{
                    //    ModelState.AddModelError("PropertyDefinition", "Property Definitions are not allowed in parent categories.");
                    //    return View(viewModel);
                    //}
                    ViewModels.ZGL.Category.Category categoryLGL = XmlHelper.ToObject<ViewModels.ZGL.Category.Category>(viewModel.PropertyDefinition);
                }
                catch (Exception ex)
                {
                    ModelState.AddModelError("PropertyDefinition", String.Format("Property Definition XML does not satisfy Zealous Graphical Language (LGL) Specification. Correct following Error and try again:<br/>{0}", ex.InnerException.Message));
                    return View(viewModel);
                }
            }

            #endregion ZGL Validation

            if (_Context.IsDuplicateCategory(viewModel.Name.ToSeoUrl(), viewModel.ID))
            {
                ModelState.AddModelError("DuplicateCategory", "This category already exists. Please choose another.");
                return View(viewModel);
            }

            Category entity = null;
            String oldCategoryName = String.Empty;
            if (viewModel.ID == 0)
            {
                entity = new Category();
                _Context.AddToCategories(entity);
            }
            else
            {
                entity = _Context.Categories.FirstOrDefault(P => P.ID == viewModel.ID);
                oldCategoryName = entity.Name;
            }

            entity = Mapper.Map<CategoryViewModel, Category>(viewModel, entity);
            entity.UrlName = entity.Name.ToSeoUrl();

            if (entity.ParentID == 0)
                entity.ParentID = null;

            _Context.SaveChanges();
            ///Fire Category Update Events
            if(viewModel.ID == 0)
                JbEvents.CategoryAdded(entity, _Context);
            else
                JbEvents.CategoryUpdated(entity, oldCategoryName, _Context);
            //return RedirectToAction("List");
            return RedirectToAction(String.Format("Edit/{0}", entity.ID), new { IsSaved = "true" });
        }		
		#endregion Action Methods
		
		#region Helper Methods

		/// <summary>
        /// Builds a ListConfig object with a list of Category
        /// </summary>
        /// <returns></returns>
		private ListConfig BuildCategoryListConfig()
		{
			UtilityDAO dao = new UtilityDAO();
            //Jb.Domain.DbParameter[] parameters = new[]{
                //new Jb.Domain.DbParameter("@JobSeekerID", LoggedInUser.JobSeekerID)
            //};
            DataSet ds = dao.GetDataSet(DbObject.SP.GET_CATEGORY_LIST, null, true);
            ListConfig listConfig = new ListConfig(ds.Tables[0], null);
            return listConfig;
		}

        #endregion			
    }
}


